package vip.liux.contracts.shared.consts;

import org.apache.commons.lang3.reflect.ConstructorUtils;
import org.springframework.beans.BeanWrapper;
import org.springframework.beans.BeanWrapperImpl;

import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.time.ZoneId;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.util.Map;

public interface GeneralConstants {

    BigDecimal MAX_BIG_DECIMAL = new BigDecimal("999999999.99");

    DateTimeFormatter PURE_DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyyMMddHHmmss");

    DateTimeFormatter NORM_DATETIME_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");

    DateTimeFormatter UTC_WITH_XXX_OFFSET_FORMATTER = DateTimeFormatter.ofPattern("yyyy-MM-dd'T'HH:mm:ssXXX");

    static LocalDateTime of(Date date) {
        return date.toInstant()
                .atZone(ZoneId.systemDefault())
                .toLocalDateTime();
    }

    /**
     * 通过无参构造创建实例
     *
     * @param clazz 目标类
     * @param <T>   类型
     * @return 实例对象
     */
    static <T> T newInstance(Class<T> clazz) {
        try {
            return clazz.getDeclaredConstructor().newInstance();
        } catch (Exception e) {
            throw new RuntimeException("Failed to instantiate: " + clazz, e);
        }
    }

    /**
     * 通过带参数的构造方法创建实例
     *
     * @param clazz      目标类
     * @param paramTypes 构造参数类型
     * @param params     构造参数值
     * @param <T>        类型
     * @return 实例对象
     */
    static <T> T newInstance(Class<T> clazz, Class<?>[] paramTypes, Object[] params) {
        try {
            return ConstructorUtils.invokeConstructor(clazz, params);
            // return clazz.getDeclaredConstructor(paramTypes).newInstance(params);
        } catch (Exception e) {
            throw new RuntimeException("Failed to instantiate: " + clazz, e);
        }
    }

    /**
     * 将 Map 转换为指定类型的 Bean
     *
     * @param map   属性Map
     * @param clazz Bean的Class
     * @param <T>   Bean类型
     * @return Bean对象
     */
    static <T> T mapToBean(Map<String, ?> map, Class<T> clazz) {
        try {
            map.remove("@class"); // 移除可能存在的 @class 属性
            T bean = clazz.getDeclaredConstructor().newInstance();
            BeanWrapper beanWrapper = new BeanWrapperImpl(bean);
            beanWrapper.setPropertyValues(map);
            return bean;
        } catch (Exception e) {
            throw new RuntimeException("Map转Bean失败: " + clazz.getName(), e);
        }
    }
}
